#include "valuelist.h"

ValueList::	ValueList(std::string id, int x, int y, int size_x, int size_y, ALLEGRO_FONT* label_font,
		int entry_height, int padding, std::string background_graphic, std::string entry_graphic_active,
		std::string entry_graphic_inactive, const unsigned char label_color[3], int scrollbar_width,
		int scrollbar_button_height, int scrollbar_slider_padding, std::string scrollbar_slider_background_graphic,
		int scrollbar_slider_height, std::string scrollbar_slider_graphic_up,
		std::string scrollbar_slider_graphic_down, std::string scrollbar_button_graphic_top_up,
		std::string scrollbar_button_graphic_top_down, std::string scrollbar_button_graphic_bottom_up,
		std::string scrollbar_button_graphic_bottom_down)
	: GuiElement(id, x, y, size_x, size_y)
{
	m_active_entry = -1;

	m_label_font = label_font;
	m_label_color = al_map_rgb(label_color[0], label_color[1], label_color[2]);
	m_entry_height = entry_height;
	m_padding = padding;
	m_scrollbar_width = scrollbar_width;
	m_background_graphic = background_graphic;
	m_entry_graphic_active = entry_graphic_active;
	m_entry_graphic_inactive = entry_graphic_inactive;

	// Create the scrollbar.
	m_scrollbar = new ScrollBar(m_id + "_scrollbar", m_x + m_size_x - m_padding - m_scrollbar_width, m_y + m_padding,
		m_scrollbar_width, m_size_y - 2 * m_padding);
}

ValueList::~ValueList()
{
	delete m_scrollbar;
	al_destroy_font(m_label_font);
}

void ValueList::AddEntry(std::string label, std::string value)
{
	// Add to the list.
	m_entry_list.push_back(std::make_pair(label, value));

	// Determine the number of entries that fit into the list.
	unsigned entries_to_draw = (m_size_y - 2 * m_padding) / m_entry_height;

	// If there are not enough entries to fill the list, scrolling is to do nothing. If there are, determine how
	// much one button click should scroll.
	if (m_entry_list.size() <= entries_to_draw)
		m_scrollbar->set_step(0.0f);
	else
		m_scrollbar->set_step(1.0f / (m_entry_list.size() - entries_to_draw));
}

bool ValueList::GetCurrentValue(std::string& value)
{
	// Find the value and save it is possible.
	if (m_active_entry >= 0 && m_active_entry < (int)m_entry_list.size())
	{
		value = m_entry_list.at(m_active_entry).second;
		return true;
	}

	return false;
}

void ValueList::PrimaryMouseButtonUp(int x, int y)
{
	m_scrollbar->PrimaryMouseButtonUp(x, y);
}

void ValueList::PrimaryMouseButtonDown(int x, int y)
{
	// We hit the entries.
	if (x >= m_x + m_padding && x < m_x + m_size_x - m_scrollbar_width - m_padding
		&& y >= m_y + m_padding && y < m_y + m_size_y - m_padding)
	{
		// Which one did we hit?
		unsigned entries_to_draw = (m_size_y - 2 * m_padding) / m_entry_height;
		unsigned start_entry = (m_entry_list.size() >= entries_to_draw)
			? m_scrollbar->value() * (m_entry_list.size() - entries_to_draw)
			: 0;

		unsigned entry_hit = start_entry + (y - (m_y + m_padding)) / m_entry_height;
		
		if (entry_hit < m_entry_list.size())
			m_active_entry = entry_hit;
	}	

	m_scrollbar->PrimaryMouseButtonDown(x, y);
}

void ValueList::MouseAxisChange(int x, int y)
{
	m_scrollbar->MouseAxisChange(x, y);
}

void ValueList::Update()
{
	m_scrollbar->Update();
}

void ValueList::Draw()
{
	// Draw the background.
	ALLEGRO_BITMAP* graphic = allegro_bitmap_resource_manager.GetResource(m_background_graphic);
	al_draw_scaled_bitmap(graphic, 0, 0, al_get_bitmap_width(graphic), al_get_bitmap_height(graphic),
		m_x, m_y, m_size_x, m_size_y, NULL);

	// Determine how many entities fit into the box and, based on the value of the scrollbar, on which element we
	// begin to draw.
	unsigned entries_to_draw = (m_size_y - 2 * m_padding) / m_entry_height;
	unsigned start_entry = (m_entry_list.size() >= entries_to_draw)
		? m_scrollbar->value() * (m_entry_list.size() - entries_to_draw)
		: 0;

	// Draw them all.
	for (unsigned i = start_entry; i < start_entry + entries_to_draw && i < m_entry_list.size(); i++)
	{
		// Either active or inactive, based on their state.
		if (i == m_active_entry)
			graphic = allegro_bitmap_resource_manager.GetResource(m_entry_graphic_active);
		else
			graphic = allegro_bitmap_resource_manager.GetResource(m_entry_graphic_inactive);
		
		al_draw_scaled_bitmap(graphic, 0, 0, al_get_bitmap_width(graphic), al_get_bitmap_height(graphic),
			m_x + m_padding, m_y + m_padding + (i - start_entry) * m_entry_height, m_size_x - 2 * m_padding - m_scrollbar_width,
			m_entry_height, NULL);

		// Draw the label.
		al_draw_text(m_label_font, m_label_color, m_x + m_padding + 5,
			m_y + m_padding + (i - start_entry) * m_entry_height + m_entry_height / 2 - al_get_font_line_height(m_label_font) / 2,
			ALLEGRO_ALIGN_LEFT, m_entry_list.at(i).first.c_str());
	}

	m_scrollbar->Draw();
}